package org.jackysoft.service.impl;

import java.util.Collection;

import javax.annotation.Resource;

import org.jackysoft.entity.Department;
import org.jackysoft.entity.DepartmentType;
import org.jackysoft.entity.Role;
import org.jackysoft.entity.User;
import org.jackysoft.entity.WorkflowSetting;
import org.jackysoft.entity.WorkflowSettingPK;
import org.jackysoft.google.collection.DepartmentZtreeFunction;
import org.jackysoft.google.collection.RoleZtreeFunction;
import org.jackysoft.google.collection.UserZtreeFunction;
import org.jackysoft.google.collection.ZTreeNode;
import org.jackysoft.service.AbstractStringIdServiceImpl;
import org.jackysoft.service.ComponentService;
import org.jackysoft.service.DepartmentService;
import org.jackysoft.service.UserService;
import org.jackysoft.service.WorkflowSettingService;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;

@Service
@Transactional
public class ComponentServiceImpl extends
		AbstractStringIdServiceImpl<ZTreeNode> implements ComponentService {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7891795646629965916L;
	private DepartmentService service;
	private WorkflowSettingService settingService;
	private UserService userService;

	@Override
	public void deleteUser(User owner) throws DataAccessException {
		userService.marked4Remove(owner);

	}

	@Override
	public Collection<ZTreeNode> getZTreeNodes(Department bean, Role role,
			WorkflowSettingPK settingId) throws DataAccessException {
		Collection<Department> depts = Lists.newArrayList();
		Collection<Role> roles = Lists.newArrayList();
		Collection<ZTreeNode> jsNodes = Lists.newArrayList();
		WorkflowSetting wset = null;
		if (settingId != null)
			wset = settingService.get(settingId);
		if (bean == null) {
			bean = new Department();
			bean.setId("root");
		}
		if ("root".equals(bean.getId())) {
			if (wset != null) {
				if (wset.getDepartments().size() > 0) {
					depts = wset.getDepartments();
					jsNodes = (Collections2.transform(depts,
							new DepartmentZtreeFunction()));
				}
				if (wset.getRoles().size() > 0) {
					roles = wset.getRoles();
					jsNodes = (Collections2.transform(roles,
							new RoleZtreeFunction()));
				}
			} else {
				depts = service.getChildren("root");
				jsNodes = (Collections2.transform(depts,
						new DepartmentZtreeFunction()));
			}

		} else {
			Collection<User> users = Lists.newArrayList();
			if (wset != null) {
				if (wset.getRoles().size() > 0) {
					users = userService.getsByRoles(wset.getRoles());

					Collection<ZTreeNode> jsNode = Collections2.transform(
							users, new UserZtreeFunction());
					jsNodes.addAll(jsNode);
				} else {
					Department theDept = this.service.get(bean.getId());
					users = userService.gets(theDept);
					Collection<Department> children = service.getChildren(theDept);

					Collection<ZTreeNode> jsNode = Collections2.transform(
							depts, new DepartmentZtreeFunction());
					jsNodes.addAll(jsNode);

					jsNode = Collections2.transform(children,
							new DepartmentZtreeFunction());
					jsNodes.addAll(jsNode);

					jsNode = Collections2.transform(users,
							new UserZtreeFunction());
					jsNodes.addAll(jsNode);

				}
			} else {
				Department theDept = this.service.get(bean.getId());

				users = userService.gets(theDept);
				depts = this.service.getChildren(theDept);

				Collection<ZTreeNode> jsNode = Collections2.transform(depts,
						new DepartmentZtreeFunction());
				jsNodes.addAll(jsNode);
				jsNode = Collections2.transform(users, new UserZtreeFunction());
				jsNodes.addAll(jsNode);
			}

		}

		return jsNodes;
	}

	@Override
	public Collection<ZTreeNode> getZTreeNodes(Department bean,
			Collection<DepartmentType> dtypes) throws DataAccessException {
		return service.ztree(bean, dtypes);
	}

	@Override
	public Collection<ZTreeNode> getZTreeNodes(Department bean)
			throws DataAccessException {
		return service.ztree(bean);
	}

	@Resource
	public void setService(DepartmentService service) {
		this.service = service;
	}

	@Resource
	public void setSettingService(WorkflowSettingService settingService) {
		this.settingService = settingService;
	}

	@Resource
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
}
